package com.lagou.handler;

import com.lagou.client.ZkClientUtil;
import com.lagou.listener.ProviderListener;
import com.lagou.pojo.RpcRequest;
import com.lagou.service.IUserService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Random;

/**
 * 自定义的处理器
 */
@Component
public class UserServerHandler extends ChannelInboundHandlerAdapter implements InitializingBean {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ZkClientUtil zkClientUtil;

    @Autowired
    private ProviderListener providerListener;

    private CuratorFramework zkClient;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        long beginTimeMillis = System.currentTimeMillis();
        providerListener.setBeginTimeMillis(beginTimeMillis);
        if(msg instanceof RpcRequest){
            RpcRequest rpcRequest = (RpcRequest) msg;
            String className = rpcRequest.getClassName();
            Class<?> aClass = Class.forName(className);
            //根据class获取Spring上下文的bean对象
            Object bean = applicationContext.getBean(aClass);
            IUserService userService = (IUserService) bean;
            String methodName = rpcRequest.getMethodName();
            //根据方法名，以及方法参数类型获取对应的方法
            Method method = aClass.getMethod(methodName, rpcRequest.getParameterTypes());
            Object invoke = method.invoke(userService, rpcRequest.getParameters());
            //返回执行结果
            ctx.writeAndFlush(invoke);
        } else {
            ctx.writeAndFlush("ERROR");
        }
        int random = new Random().nextInt(500) + 100;
        Thread.sleep(random);
        long endTimeMillis = System.currentTimeMillis();
        String costTime = String.valueOf(endTimeMillis - beginTimeMillis);

        System.out.println("process request cost " + costTime + " ms");

        //如果节点不存在则创建，存在更新响应时间
        if(zkClient.checkExists().forPath(zkClientUtil.getPath()) == null){
            zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(zkClientUtil.getPath(), costTime.getBytes());
        } else {
            zkClient.setData().forPath(zkClientUtil.getPath(), costTime.getBytes());
        }


    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.zkClient = zkClientUtil.getZkClient();
    }
}
